/********************************** (C) COPYRIGHT *******************************
 * File Name          : ch32x035_it.c
 * Author             : WCH
 * Version            : V1.0.0
 * Date               : 2023/12/26
 * Description        : Main Interrupt Service Routines.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#include "ch32l103.h"
#include "DevicesQueue.h"
#include "DevicesUart.h"
#include "DriverDCDC.h"
#include "ch32l103_it.h"


/*********************************************************************
 * @fn      NMI_Handler
 *
 * @brief   This function handles NMI exception.
 *
 * @return  none
 */
void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void NMI_Handler(void)
{
    while (1)
  {
  }
}

/*********************************************************************
 * @fn      HardFault_Handler
 *
 * @brief   This function handles Hard Fault exception.
 *
 * @return  none
 */
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void HardFault_Handler(void)
{
  while (1)
  {
  }
}

void vUSART1ReceiveCallback(void)
{
    static uint32_t uiMDANdtrOld = 0;
    uint32_t uiMDANdtrNow;

    while(uiMDANdtrOld != (uiMDANdtrNow = USART1_DMA_READ_LENGTH - DMA1_Channel5->CNTR))
    {
        if(uiMDANdtrNow < uiMDANdtrOld)
        {
            /* 把数据存放到队列缓存里 */
            enumQueuePushDatas(&g_TypeQueueUart1Read, &g_USART1ReadDMABuff[uiMDANdtrOld], USART1_DMA_READ_LENGTH - uiMDANdtrOld);

            uiMDANdtrOld = 0;
        }

        /* 把数据存放到队列缓存里 */
        enumQueuePushDatas(&g_TypeQueueUart1Read, &g_USART1ReadDMABuff[uiMDANdtrOld], uiMDANdtrNow - uiMDANdtrOld);

        uiMDANdtrOld = uiMDANdtrNow;
    }
}

void vUSART2ReceiveCallback(void)
{
    static uint32_t uiMDANdtrOld = 0;
    uint32_t uiMDANdtrNow;

    while(uiMDANdtrOld != (uiMDANdtrNow = USART2_DMA_READ_LENGTH - DMA1_Channel6->CNTR))
    {
        if(uiMDANdtrNow < uiMDANdtrOld)
        {
            /* 把数据存放到队列缓存里 */
            enumQueuePushDatas(&g_TypeQueueUart2Read, &g_USART2ReadDMABuff[uiMDANdtrOld], USART2_DMA_READ_LENGTH - uiMDANdtrOld);

            uiMDANdtrOld = 0;
        }

        /* 把数据存放到队列缓存里 */
        enumQueuePushDatas(&g_TypeQueueUart2Read, &g_USART2ReadDMABuff[uiMDANdtrOld], uiMDANdtrNow - uiMDANdtrOld);

        uiMDANdtrOld = uiMDANdtrNow;
    }
}

void vUSART3ReceiveCallback(void)
{
    static uint32_t uiMDANdtrOld = 0;
    uint32_t uiMDANdtrNow;

    while(uiMDANdtrOld != (uiMDANdtrNow = USART3_DMA_READ_LENGTH - DMA1_Channel3->CNTR))
    {
        if(uiMDANdtrNow < uiMDANdtrOld)
        {
            /* 把数据存放到队列缓存里 */
            enumQueuePushDatas(&g_TypeQueueUart3Read, &g_USART3ReadDMABuff[uiMDANdtrOld], USART3_DMA_READ_LENGTH - uiMDANdtrOld);
            uiMDANdtrOld = 0;
        }

        /* 把数据存放到队列缓存里 */
        enumQueuePushDatas(&g_TypeQueueUart3Read, &g_USART3ReadDMABuff[uiMDANdtrOld], uiMDANdtrNow - uiMDANdtrOld);

        uiMDANdtrOld = uiMDANdtrNow;
    }
}

/*********************************************************************
 * @fn      USART2_IRQHandler
 *
 * @brief   This function handles USART2 global interrupt request.
 *
 * @return  none
 */
void USART1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void USART1_IRQHandler(void)
{
    if(USART_GetFlagStatus(USART1, USART_FLAG_IDLE) != RESET)
    {
        vUSART1ReceiveCallback();

        /* 软件先读USART_STAT0，再读USART_DATA可清除空闲中断标志 */
        USART_ReceiveData(USART1);
    }
    else if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)
    {
        /* 软件先读USART_STAT0，再读USART_DATA可清除错误中断标志 */
        USART_ReceiveData(USART1);

        /* 重新初始化 */
        vUart1Init();
    }
    /* 错误中断 */
    else
    {
        USART_ClearFlag(USART1, USART_FLAG_CTS);
        USART_ClearFlag(USART1, USART_FLAG_LBD);
        USART_ClearFlag(USART1, USART_FLAG_TC);
        USART_ClearFlag(USART1, USART_FLAG_NE);
        USART_ClearFlag(USART1, USART_FLAG_FE);
        USART_ClearFlag(USART1, USART_FLAG_PE);

        /* 软件先读USART_STAT0，再读USART_DATA可清除错误xxx中断标志 */
        USART_ReceiveData(USART1);
    }
}

/*!
    \brief      this function handles DMA interrupt request
    \param[in]  none
    \param[out] none
    \retval     none
*/
void DMA1_Channel5_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void DMA1_Channel5_IRQHandler(void)
{
    if(DMA_GetITStatus(DMA1_IT_TC5) != RESET)
    {
        DMA_ClearITPendingBit(DMA1_IT_TC5);

        vUSART1ReceiveCallback();
    }
    else if(DMA_GetITStatus(DMA1_IT_HT5) != RESET)
    {
        DMA_ClearITPendingBit(DMA1_IT_HT5);

        vUSART1ReceiveCallback();
    }
}

/*********************************************************************
 * @fn      USART2_IRQHandler
 *
 * @brief   This function handles USART2 global interrupt request.
 *
 * @return  none
 */
void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void USART2_IRQHandler(void)
{
    if(USART_GetFlagStatus(USART2, USART_FLAG_IDLE) != RESET)
    {
        vUSART2ReceiveCallback();

        /* 软件先读USART_STAT0，再读USART_DATA可清除空闲中断标志 */
        USART_ReceiveData(USART2);
    }
    else if(USART_GetFlagStatus(USART2, USART_FLAG_ORE) != RESET)
    {
        /* 软件先读USART_STAT0，再读USART_DATA可清除错误中断标志 */
        USART_ReceiveData(USART2);

        /* 重新初始化 */
        vUart2Init();
    }
    /* 错误中断 */
    else
    {
        USART_ClearFlag(USART2, USART_FLAG_CTS);
        USART_ClearFlag(USART2, USART_FLAG_LBD);
        USART_ClearFlag(USART2, USART_FLAG_TC);
        USART_ClearFlag(USART2, USART_FLAG_NE);
        USART_ClearFlag(USART2, USART_FLAG_FE);
        USART_ClearFlag(USART2, USART_FLAG_PE);

        /* 软件先读USART_STAT0，再读USART_DATA可清除错误xxx中断标志 */
        USART_ReceiveData(USART2);
    }
}

/*!
    \brief      this function handles DMA interrupt request
    \param[in]  none
    \param[out] none
    \retval     none
*/
void DMA1_Channel6_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void DMA1_Channel6_IRQHandler(void)
{
    if(DMA_GetITStatus(DMA1_IT_TC6) != RESET)
    {
        DMA_ClearITPendingBit(DMA1_IT_TC6);

        vUSART2ReceiveCallback();
    }
    else if(DMA_GetITStatus(DMA1_IT_HT6) != RESET)
    {
        DMA_ClearITPendingBit(DMA1_IT_HT6);

        vUSART2ReceiveCallback();
    }
}

/*********************************************************************
 * @fn      USART3_IRQHandler
 *
 * @brief   This function handles USART3 global interrupt request.
 *
 * @return  none
 */
void USART3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void USART3_IRQHandler(void)
{
    if(USART_GetFlagStatus(USART3, USART_FLAG_IDLE) != RESET)
    {
        vUSART3ReceiveCallback();

        /* 软件先读USART_STAT0，再读USART_DATA可清除空闲中断标志 */
        USART_ReceiveData(USART3);
    }
    else if(USART_GetFlagStatus(USART3, USART_FLAG_ORE) != RESET)
    {
        /* 软件先读USART_STAT0，再读USART_DATA可清除错误中断标志 */
        USART_ReceiveData(USART3);

        /* 重新初始化 */
        vUart3Init();
    }
    /* 错误中断 */
    else
    {
        USART_ClearFlag(USART3, USART_FLAG_CTS);
        USART_ClearFlag(USART3, USART_FLAG_LBD);
        USART_ClearFlag(USART3, USART_FLAG_TC);
        USART_ClearFlag(USART3, USART_FLAG_NE);
        USART_ClearFlag(USART3, USART_FLAG_FE);
        USART_ClearFlag(USART3, USART_FLAG_PE);

        /* 软件先读USART_STAT0，再读USART_DATA可清除错误xxx中断标志 */
        USART_ReceiveData(USART3);
    }
}

/*!
    \brief      this function handles DMA interrupt request
    \param[in]  none
    \param[out] none
    \retval     none
*/
void DMA1_Channel3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void DMA1_Channel3_IRQHandler(void)
{
    if(DMA_GetITStatus(DMA1_IT_TC3) != RESET)
    {
        DMA_ClearITPendingBit(DMA1_IT_TC3);

        vUSART3ReceiveCallback();
    }
    else if(DMA_GetITStatus(DMA1_IT_HT3) != RESET)
    {
        DMA_ClearITPendingBit(DMA1_IT_HT3);

        vUSART3ReceiveCallback();
    }
}

void TIM3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void TIM3_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
    {
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);

        cDCDCxControl();
    }
}

void SysTick_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void SysTick_Handler(void)
{
    SysTick->SR = 0;
}
